/**
 * 
 */
package OfficeServer.users;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.logging.Level;

import OfficeServer.log_error.UserException;
import OfficeServer.main.Main;
import OfficeServer.office.Calendar;

/**
 * @author mramsey3
 * 
 */
public class UserList implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static ArrayList<User> userList = new ArrayList<User>();

    /**
     * @author mramsey3
     * @return The size of the userlist
     */
    public static int size() {
	return userList.size();
    }

    public static Patient getPatient(int patientID) {
	for (User user : userList) {
	    if ((user.getId() == patientID)
		    && (user.getAccessLevel() == AccessLevel.PATIENT)) {
		return (Patient) user;
	    }
	}
	return null;
    }

    public static Doctor getDoctor(int doctorID) {
	for (User user : userList) {
	    if ((user.getId() == doctorID)
		    && (user.getAccessLevel() == AccessLevel.DOCTOR)) {
		return (Doctor) user;
	    }
	}
	return null;
    }

    /**
     * @author Chris Bayruns
     * @param name
     *            The username to search for
     * @return The corresponding User object, null if not found
     * @throws UserException
     */
    public static User searchForUsername(String userName) throws UserException {
	User result = null;

	for (User user : userList) {
	    if (user.getUsername().equals(userName) && user.isActive()) {
		result = user;
	    }
	}

	if (result == null) {
	    throw (new UserException(Level.INFO,
		    UserException.REASON.NO_ACCOUNT, "User Search: " + userName));
	}
	return result;
    }

    /**
     * @author Chris Bayruns
     * @param name
     *            The ID to search for
     * @param level
     *            The corresponding level
     * @return The corresponding User object, null if not found
     * @throws UserException
     */
    public static User searchForID(int id, AccessLevel level)
	    throws UserException {
	User result = null;

	for (User user : userList) {
	    if (user.getId() == id && user.getAccessLevel() == level
		    && user.isActive()) {
		result = user;
	    }
	}

	if (result == null) {
	    throw (new UserException(Level.INFO,
		    UserException.REASON.NO_ACCOUNT, "User Search: " + id + " "
			    + level));
	}
	return result;
    }

    /**
     * @author Chris Bayruns
     * @param firstName
     *            The first name
     * @param lastName
     *            The last name
     * @return The corresponding User object, null if not found
     * @throws UserException
     */
    public static User searchForName(String firstName, String lastName)
	    throws UserException {
	User result = null;

	for (User user : userList) {
	    if (user.getFirstName().equals(firstName)
		    && user.getLastName().equals(lastName) && user.isActive()) {
		result = user;
	    }
	}

	if (result == null) {
	    throw (new UserException(Level.INFO,
		    UserException.REASON.NO_ACCOUNT, "User Search: "
			    + firstName + " " + lastName));
	}
	return result;
    }

    /**
     * @author Chris Bayruns
     * @param user
     *            The user to add
     */
    public static void addUser(User user) {
	try {
	    userList.add(user);
	} catch (Exception e) {
	    userList = new ArrayList<User>();
	    userList.add(user);
	}
    }

    /**
     * @author Matt
     * @param firstName
     *            The first name
     * @param lastName
     *            The last name
     * @param username
     *            The user name
     * @param password
     *            The password
     * @param accessLevel
     *            The access level
     * @throws UserException
     */
    public static void addUser(String firstName, String lastName,
	    String username, String password, AccessLevel accessLevel)
	    throws UserException {
	User temp;
	switch (accessLevel) {
	case PATIENT:
	    temp = new Patient(firstName, lastName, username, password);
	    break;
	case DOCTOR:
	    temp = new Doctor(firstName, lastName, username, password);
	    Calendar.discoverNewDoctor();
	    break;
	case NURSE:
	    temp = new Nurse(firstName, lastName, username, password);
	    break;
	case ADMIN:
	    temp = new Admin(firstName, lastName, username, password);
	    break;
	default:
	    throw (new UserException(Level.INFO,
		    UserException.REASON.INVALID_ACCESS_LEVEL, ""));
	}
	// System.out.println( "Count: " + Doctor.getCounter());
	if (!userList.contains(temp)) {
	    userList.add(temp);
	} else {
	    throw (new UserException(Level.INFO,
		    UserException.REASON.ALL_READY_EXISTS, "User Add: "
			    + username));
	}
    }

    /**
     * @author Chris Bayruns
     * @param user
     *            The user to delete
     * @throws UserException
     */
    public static void delUser(int id, AccessLevel level) throws UserException {
	boolean flag = false;
	for (User search : userList) {
	    if (search.getId() == id && search.getAccessLevel() == level) {
		search.deactivate();
		flag = true;
	    }
	}
	if (flag) {
	    throw (new UserException(Level.INFO,
		    UserException.REASON.NO_ACCOUNT, "User Del: " + id + " "
			    + level));
	}

    }

    /**
     * @author Chris Bayruns
     * @param user
     *            The user to delete
     */
    public static void delUser(User user) {
	user.deactivate();

    }

    /**
     * @author Chris Bayruns Added for debugging.
     */
    public static void clear() {
	try {
	    userList.clear();
	    Doctor.clear();
	    Patient.clear();
	    Nurse.clear();
	} catch (Exception e) {
	    userList = new ArrayList<User>();
	}

    }

    public static ArrayList<User> getUserList() {
	return userList;
    }

    public static void setUserList(ArrayList<User> userListToSet) {
	userList = userListToSet;
    }
}
